package com.xiaoxin.service;

import cn.hutool.core.collection.CollUtil;
import com.xiaoxin.autoconfig.template.OssTemplate;
import com.xiaoxin.commons.utils.Constants;
import com.xiaoxin.dubbo.api.MovementApi;
import com.xiaoxin.dubbo.api.UserInfoApi;
import com.xiaoxin.dubbo.api.VisitorsApi;
import com.xiaoxin.exception.BusinessException;
import com.xiaoxin.interceptor.UserHolder;
import com.xiaoxin.model.domain.UserInfo;
import com.xiaoxin.model.mongo.Movement;
import com.xiaoxin.model.mongo.Visitors;
import com.xiaoxin.model.vo.ErrorResult;
import com.xiaoxin.model.vo.MovementsVo;
import com.xiaoxin.model.vo.PageResult;
import com.xiaoxin.model.vo.VisitorsVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author xiaoxiaode
 * @date 2021-09-03-19:30
 **/
@Slf4j
@Service
public class MovementService {

    @Autowired
    private OssTemplate ossTemplate;

    @DubboReference
    private MovementApi movementApi;

    @DubboReference
    protected UserInfoApi userInfoApi;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @DubboReference
    private VisitorsApi visitorsApi;

    /*
     * 发布动态
     * */
    public void publishMovement(Movement movement, MultipartFile[] imageContent) throws IOException {
        // 判断当前发布动态的内容是否存在
        if (StringUtils.isEmpty(movement.getTextContent())) {
            throw new BusinessException(ErrorResult.contentError());
        }
        // 获取当前登录的用户id
        Long UserId = UserHolder.getId();
        // 将文件上传到阿里云oss,获取请求地址
        List<String> medias = new ArrayList<>();
        for (MultipartFile multipartFile : imageContent) {
            String upload = ossTemplate.upload(multipartFile.getOriginalFilename(), multipartFile.getInputStream());
            medias.add(upload);
        }
        // 将数据封装到movement对象
        movement.setUserId(UserId);
        movement.setMedias(medias);
        // 调用api完成发布动态
        movementApi.publish(movement);
    }

    /*
     * 查询个人动态
     * */
    public PageResult findByUserId(Long userId, Integer page, Integer pagesize) {
        // 根据用户id,查询个人动态内容
        PageResult pageResult = movementApi.findByUserId(userId, page, pagesize);
        // 获取pageResult中的items
        List<Movement> items = (List<Movement>) pageResult.getItems();
        if (items == null) {
            return pageResult;
        }
        UserInfo userInfo = userInfoApi.findById(userId);
        List<MovementsVo> vos = new ArrayList<>();
        for (Movement item : items) {
            // 构建vo对象
            MovementsVo vo = MovementsVo.init(userInfo, item);
            vos.add(vo);
        }
        pageResult.setItems(vos);
        return pageResult;
    }

    /*
     * 查询好友动态
     * */
    public PageResult findFriendMovement(Integer page, Integer pagesize) {
        // 获取当前用户的id
        Long userId = UserHolder.getId();
        // 调用api查询当前用户好友发布的动态列表
        List<Movement> movements = movementApi.findFriendMovement(page, pagesize, userId);
        return getPageResult(page, pagesize, movements);
    }

    private PageResult getPageResult(Integer page, Integer pagesize, List<Movement> movements) {
        // 判断列表是否为空
        if (CollUtil.isEmpty(movements)) {
            return new PageResult();
        }
        // 提取动态发布人的ID
        List<Long> list = CollUtil.getFieldValues(movements, "userId", Long.class);
        // 根据用户的id获取用户信息
        Map<Long, UserInfo> userInfoMap = userInfoApi.findByIds(list, null);
        // 构造动态集合
        List<MovementsVo> vos = new ArrayList<>();
        for (Movement movement : movements) {
            UserInfo userInfo = userInfoMap.get(movement.getUserId());
            if (userInfo != null) {
                MovementsVo vo = MovementsVo.init(userInfo, movement);
                // 判断hashKey是否存在
                String key = Constants.MOVEMENTS_INTERACT_KEY + movement.getId().toHexString();
                String hashKey = Constants.MOVEMENT_LIKE_HASHKEY + UserHolder.getId();
                if (redisTemplate.opsForHash().hasKey(key, hashKey)) {
                    vo.setHasLiked(1);
                }
                String loveHashKey = Constants.MOVEMENT_LOVE_HASHKEY + UserHolder.getId();
                if (redisTemplate.opsForHash().hasKey(key, loveHashKey)) {
                    vo.setHasLoved(1);
                }
                vos.add(vo);
            }
        }
        return new PageResult(page, pagesize, 0L, vos);
    }

    /*
     * 查询推荐动态
     * */
    public PageResult recommendMovement(Integer page, Integer pagesize) {
        // 从redis中获取推荐数据
        // MOVEMENTS_RECOMMEND_158
        String redisKey = Constants.MOVEMENTS_RECOMMEND + UserHolder.getId();
        // 判断推荐数据是否存在
        // "106,12,133,24"
        String redisValue = redisTemplate.opsForValue().get(redisKey);
        List<Movement> list = Collections.EMPTY_LIST;
        if (StringUtils.isEmpty(redisValue)) {
            // 不存在调用api随机构建
            list = movementApi.randomMovement(pagesize);
        } else {
            // 调用api根据pid查询动态数据
            String[] values = redisValue.split(",");
            if ((page - 1) * pagesize < values.length) {
                List<Long> collect = Arrays.stream(values).skip((page - 1) * pagesize)
                        .limit(pagesize)
                        .map(e -> Long.valueOf(e))
                        .collect(Collectors.toList());
                list = movementApi.findMovementByPids(collect);
            }
        }
        // 构造返回值
        return getPageResult(page, pagesize, list);
    }

    /*
     * 查看单条动态
     * */
    public MovementsVo findById(String movementId) {
        // 根据id查询动态详情
        Movement movement = movementApi.findById(movementId);
        // 转化vo对象
        if (movement != null) {
            UserInfo userInfo = userInfoApi.findById(movement.getUserId());
            return MovementsVo.init(userInfo, movement);
        } else {
            return null;
        }
    }

    /*
     * 首页-访问列表
     * */
    public List<VisitorsVo> queryVisitorsList() {
        // 查询访问时间
        String key = Constants.VISITORS_USER;
        String hashKey = String.valueOf(UserHolder.getId());
        String value = (String) redisTemplate.opsForHash().get(key, hashKey);
        Long date = StringUtils.isEmpty(value) ? null : Long.valueOf(value);
        // 查询数据列表 list<visitors>
        List<Visitors> visitors=visitorsApi.find(date,UserHolder.getId());
        if(CollUtil.isEmpty(visitors)){
            return new ArrayList<>();
        }
        // 提取用户id
        List<Long> ids = CollUtil.getFieldValues(visitors, "visitorUserId", Long.class);
        // 查看用户详情
        Map<Long, UserInfo> infoMap = userInfoApi.findByIds(ids, null);
        // 构造返回
        List<VisitorsVo> vos=new ArrayList<>();
        for (Visitors visitor : visitors) {
            UserInfo userInfo = infoMap.get(visitor.getVisitorUserId());
            if(userInfo!=null){
                VisitorsVo vo = VisitorsVo.init(userInfo, visitor);
                redisTemplate.opsForHash().put(key, hashKey,visitor.getDate().toString());
                vos.add(vo);
            }
        }
        return vos;
    }
}
